package com.jian.mygame;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.jbox2d.collision.PolygonShape;
import org.jbox2d.collision.ShapeType;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.contacts.ContactPoint;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.Log;

public class GameObjectCollection extends Object{
	private Context mContext = null;
	private MyWorld mWorld = null;
	private ArrayList<GameObject> mGameObjectList = new ArrayList<GameObject>();
	
	public GameObjectCollection( Context context ) {
		mContext = context;
		
		// Create Box2D World
        mWorld = new MyWorld();
        mWorld.CreateWorld(context);
	}
	
	protected void updateContact(Canvas canvas) {
		ContactPoint cp = null;
		MyAnimation anima = null;
		int sizeCP = mWorld.mContactListner.mContactPoint.size();
		
		for( int i =0; i<sizeCP; i++) {
			cp = mWorld.mContactListner.mContactPoint.get(i);
			Body body1 = cp.shape1.getBody();
			Body body2 = cp.shape2.getBody();
			BodyExtend bodyextend1, bodyextend2;
			bodyextend1 = (BodyExtend)(body1.getUserData());
			bodyextend2 = (BodyExtend)(body2.getUserData());
    		//DrawContact( canvas, cp.position.x*MyWorld.RATE, cp.position.y*MyWorld.RATE);
			
			//Shape1
			anima = bodyextend1.getAnimation();
			if( anima != null ) {
				anima.setPosition( (int)(body1.getPosition().x*MyWorld.RATE), (int)(body1.getPosition().y*MyWorld.RATE) );
				anima.start();
			}
			bodyextend1.contactedBy(bodyextend2);
			
			//Shape2
			anima = bodyextend2.getAnimation();
			if( anima != null ) {
				anima.setPosition( (int)(body2.getPosition().x*MyWorld.RATE), (int)(body2.getPosition().y*MyWorld.RATE) );
				anima.start();
			}
			bodyextend2.contactedBy(bodyextend1);
			
		}
		//mAnimation.onDraw( canvas );
		mWorld.mContactListner.mContactPoint.clear();
	}
	
	
	protected Iterator<GameObject> getGameObjectIterator() {
		return mGameObjectList.iterator();
	}
	
	protected void destroy( GameObject gameobj ){
		mGameObjectList.remove(gameobj);
	}
	
	public void CreateWall( float x0, float y0, float x1, float y1 ) {
		float x = (x0+x1)/2;
		float y = (y0+y1)/2;
		float distance = (float) Math.sqrt( (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1) );
		float angle = (float)Math.atan((y1-y0)/(x1-x0));
		
		createSimpleBoxCenter(x, y, distance, 1, angle, 
				              Color.BLUE, true, true, BodyExtend.ROLE_WALL );
	}
	
	public void TestCreatePolygon() {
		Vec2[] vec = {
			           new Vec2(50f,  150f),
				       new Vec2(100f, 150f), //Bad
				       new Vec2(100f, 100f),
				       new Vec2(150f, 150f),
				       new Vec2(100f, 250f),
					};

		CreatePolygon( vec );
	}
	
	public void CreatePolygon( Vec2 vec[]) {
		float x, y;
		
		//Take the first position as Body position
		x = vec[0].x;
		y = vec[0].y;
		Log.d("GameHandler","x: "+x+" /y: "+y);
		for( int i=0; i<vec.length; i++) {
			vec[i].x -= x;
			vec[i].y -= y;
			Log.d("GameHandler","vec["+i+"].x: "+ vec[i].x + " / vec["+i+"].y: "+vec[i].y);
		}
		
		//Filter Vertex
		MyPolygon polygon = new MyPolygon(vec);
		Vec2[] newVec = polygon.filterVertex();
		
		createPolygon(newVec, x, y, 0.0f,
				      Color.BLUE, true, false, BodyExtend.ROLE_WALL);
	}
	
    
	/*
	public void fire( float x, float y, Vec2 vec, float angle, int type ) {
		Body body = null;
		//int size = MyFactory.mBulletRes.length;
		//int type = random_num%size;
		
		body = createBody(x, y, angle, MyFactory.mBulletRes[type], MyFactory.mAnimationRes[1], BodyExtend.ROLE_BULLET, false);
        body.applyForce( vec , body.getPosition());
	}
	*/
	
	public void loadTools() {
		float x, y, angle;
		//int type;
		
		for( int i = 0; i < MyFactory.mToolRes.length; i++) {
			x = MyFactory.mToolRes[i].mInitPos.mPosX;
			y = MyFactory.mToolRes[i].mInitPos.mPosY;
			angle = MyFactory.mToolRes[i].mInitPos.mAngle;
			createBody(x, y, angle, MyFactory.mToolRes[i], null, BodyExtend.ROLE_TOOL, true);
		}
	}
	
	private void createBody( float x, float y, float angle, ResourceInfo tool, AnimationInfo anima_info, int role, boolean isStatic) {
        int shapeType = tool.mShapeType;
        
        switch( shapeType ){
        case MyFactory.TOOL_TYPE_CIRCLE :
        	createCircle(x, y, angle, 
	      			     isStatic, true, role,
	    			     tool, anima_info );
        	break;
        case MyFactory.TOOL_TYPE_BOX:
        	createBox(x, y, angle, 
        			  isStatic, true, role,
        			  tool, anima_info );
        	break;
        default:
        	break;
        }
	}
	
    public void createBox(float x,float y,  float angle, 
                          boolean isStatic, boolean isDrawable, int role,
    					  ResourceInfo tool, AnimationInfo anima_info ){ 
    	Body body = null;
    	BodyExtend bodyextend = null;
    	GameObject gameobj = null;
    	
    	Resources res = mContext.getResources();
        int imageID = tool.mImageID;
    	Drawable image = res.getDrawable(imageID);
    	float half_width, half_height;
    	half_width = image.getIntrinsicWidth()/2;
    	half_height = image.getIntrinsicHeight()/2;

		bodyextend = new BodyExtend(mContext, Color.WHITE, isDrawable, role, image, anima_info, tool.mSoundID );
    	body = mWorld.createBox(x, y, half_width, half_height, angle, tool.mDensity, tool.mFriction, tool.mRestitution, isStatic, bodyextend);

		gameobj = new GameObject( body, bodyextend );
		mGameObjectList.add(gameobj);
    }
    
    public void createCircle(float x,float y,  float angle, 
    						 boolean isStatic, boolean isDrawable, int role,
			                 ResourceInfo tool, AnimationInfo anima_info ){ 
	
    	Body body = null;
    	BodyExtend bodyextend = null;
    	GameObject gameobj = null;
    	
    	Resources res = mContext.getResources();
        int imageID = tool.mImageID;
    	Drawable image = res.getDrawable(imageID);
		float radius = image.getIntrinsicWidth()/2;
		
    	bodyextend = new BodyExtend(mContext, Color.WHITE, isDrawable, role, image, anima_info, tool.mSoundID );
    	body = mWorld.createCircle(x, y, radius, angle, tool.mDensity, tool.mFriction, tool.mRestitution, isStatic, bodyextend);
		gameobj = new GameObject( body, bodyextend );
		mGameObjectList.add(gameobj);	
	}
    
    protected void createSimpleBox(float xTopLeft, float yTopLeft, float width, float height, 
    		                     int colorIdx, boolean isDrawable, boolean isStatic, int role ){
    	createSimpleBoxCenter(xTopLeft+width/2, yTopLeft+height/2, width/2, height/2, 0.0f, 
    	                      colorIdx,isDrawable, isStatic, role);
    }
    
    protected void createSimpleBoxCenter(float x,float y,float half_width,float half_height, float angle, 
	  		                             int colorIdx, boolean isDrawable, boolean isStatic, int role  ){ 
		Body body = null;
		BodyExtend bodyextend = null;
    	GameObject gameobj = null;
		
		bodyextend = new BodyExtend(mContext, colorIdx, isDrawable, role, null, null, 0 );    	
    	body = mWorld.createSimpleBoxCenter(x, y, half_width, half_height, angle, 
    			                            2.0f, 0.8f, 0.3f, 
    			                            colorIdx, isDrawable, isStatic, role,
    			                            bodyextend);
		gameobj = new GameObject( body, bodyextend );
		mGameObjectList.add(gameobj);	
	}
    
    protected void createPolygon(Vec2[] vec, float x, float y, float angle,
	  							 int colorIdx, boolean isDrawable, boolean isStatic, int role ){ 
		Body body = null;
		BodyExtend bodyextend = null;
    	GameObject gameobj = null;
		
    	bodyextend = new BodyExtend(mContext, colorIdx, isDrawable, role, null, null, 0 );
    	body = mWorld.createPolygon(vec, x, y, angle,
    								2.0f, 0.8f, 0.3f, 
    			                    colorIdx, isDrawable, isStatic, role,
    			                    bodyextend);
		gameobj = new GameObject( body, bodyextend );
		mGameObjectList.add(gameobj);	
    }
    
    protected void setGravity( float x, float y) {
    	mWorld.setGravity( x, y );
    }
    
    protected void updateWorld() {
    	mWorld.updateWorld();
    }
}

